package com.laogao.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import com.laogao.entity.TDocument;
import com.laogao.exception.AdxException;
import com.laogao.mapper.DocumentMapper;
import com.laogao.service.SysFileService;
import com.laogao.utils.FileUtils;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * @author gao liang
 * @date 2023-04-03 15:41
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class FileServiceImpl implements SysFileService {

    /**
     * 临时文件
     */
    @Value("${fileConfig.uploadPath}")
    private String uploadPath;

    @Value("${fileConfig.tempPath}")
    private String tempPath;

    @Value("${fileConfig.addressPrefix}")
    private String addressPrefix;

    private final DocumentMapper documentMapper;


    @Override
    public HashMap<String, Object> uploadFileNickName(MultipartFile file, HttpServletRequest request) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String suffix = originalFilename != null ? originalFilename.substring(originalFilename.lastIndexOf(".")) : ".jpg";
        String dateDir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd/"));
        File uploadDir = new File(uploadPath + dateDir);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }
        String fileName = System.currentTimeMillis() + "" + UUID.randomUUID() + suffix;
        File uploadFile = new File(uploadDir, fileName);
        file.transferTo(uploadFile);
        String url = "/fileDir/" + dateDir + fileName;
        //判断文件类型
        String extension = FilenameUtils.getExtension(fileName);
        int type = FileUtils.checkType(extension);
        String httpPath = addressPrefix + url;
        log.info("完整访问路径:{}", httpPath);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("fileName", originalFilename);
        hashMap.put("address", httpPath);
        hashMap.put("fileType", type);
        hashMap.put("systemPath", uploadPath + dateDir + fileName);
        return hashMap;
    }

    @Override
    public HashMap<String, Object> uploadFileOriginalName(MultipartFile file, HttpServletRequest request) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String dateDir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd/"));
        File uploadDir = new File(uploadPath + dateDir);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }
        File uploadFile = null;
        if (originalFilename != null) {
            uploadFile = new File(uploadDir, originalFilename);
        }
        if (uploadFile != null) {
            file.transferTo(uploadFile);
        }
        String url = "/fileDir/" + dateDir + originalFilename;
        //判断文件类型
        String extension = FilenameUtils.getExtension(originalFilename);
        int type = FileUtils.checkType(extension);
        String httpPath = addressPrefix + url;
        log.debug("完整访问路径:{}", httpPath);
        HashMap<String, Object> hashMap = new HashMap<>(4);
        hashMap.put("fileName", originalFilename);
        hashMap.put("address", httpPath);
        hashMap.put("fileType", type);
        hashMap.put("systemPath", uploadPath + dateDir + originalFilename);
        return hashMap;
    }


    @SneakyThrows
    @Override
    public void download(List<Long> ids, HttpServletResponse response) throws Exception {
        if (CollectionUtils.isEmpty(ids)) {
            throw new AdxException("ids为空");
        }
        if (ids.size() == 1) {
            TDocument clsDocument = documentMapper.selectById(ids.get(0));
            if (clsDocument != null && StringUtils.hasText(clsDocument.getAddress())) {
                File absolutPath = new File(clsDocument.getSystemPath());
                log.info("文件绝对地址:{}", clsDocument.getSystemPath());
                FileInputStream is = new FileInputStream(absolutPath);
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(clsDocument.getFileName(), "UTF-8"));
                ServletOutputStream os = response.getOutputStream();
                FileCopyUtils.copy(is, os);
            }
        }
        //多文件压缩包形式下载
        File newPath = new File(tempPath);
        if (!newPath.exists()) {
            newPath.mkdirs();
        }
        if (ids.size() > 1) {
            for (Long id : ids) {
                TDocument clsDocument = documentMapper.selectById(id);
                if (clsDocument != null && StringUtils.hasText(clsDocument.getAddress())) {
                    String absolutPath = clsDocument.getSystemPath();
                    File oldFile = new File(absolutPath);
                    //文件移动
                    FileUtil.copy(oldFile, newPath, true);
                    //获取旧名字
                    String oldFileName = getFileName(absolutPath);
                    //改名
                    renameFile(newPath + oldFileName, clsDocument.getFileName());
                }
            }
        }
        //文件夹压缩
        ZipUtil.zip(tempPath);
        //下载文件
        File zipFile = new File(tempPath + ".zip");
        FileInputStream is = new FileInputStream(zipFile);
        String downloadName = "测试文件压缩包";
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(downloadName + ".zip", "UTF-8"));
        ServletOutputStream os = response.getOutputStream();
        FileCopyUtils.copy(is, os);
        //删除文件以及压缩包
        zipFile.delete();
        FileUtil.del(tempPath);
        //关闭流
        is.close();
        os.close();
    }

    /**
     * 获取文件名
     */
    private String getFileName(String oldUrl) {
        return oldUrl.substring(oldUrl.lastIndexOf("/"));
    }

    /**
     * 文件重命名
     *
     * @param url
     * @param newName
     * @return
     * @throws Exception
     */
    public static boolean renameFile(String url, String newName) throws Exception {
        String oldUrl = url;
        oldUrl = oldUrl.replace("\\", "/");
        File old_file = new File(oldUrl);
        if (!old_file.exists()) {
            throw new IOException("文件重命名失败，文件（" + old_file + "）不存在");
        }
        System.out.println(old_file.exists());
        String old_name = old_file.getName();
        // 获得父路径
        String parent = old_file.getParent();
        // 重命名
        String new_url = parent + "/" + newName;
        File new_file = new File(new_url);
        boolean b = old_file.renameTo(new_file);
        log.info("原文件：{}", old_file.getName());
        log.info("新文件：{}", new_file.getName());
        newName = new_file.getName();
        old_name = old_file.getName();
        return !newName.equals(old_name);
    }
}
